package com.rc.evcharger.biz.log;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.rc.evcharger.common.config.FactoryDomain;
import com.rc.evcharger.common.config.MqCommandConfig;
import com.rc.evcharger.common.config.RabbitListenerConstant;
import com.rc.evcharger.common.enums.ChargePhaseEnum;
import com.rc.evcharger.common.enums.CommanderEnum;
import com.rc.evcharger.common.enums.ElecPileStopReasonEnum;
import com.rc.evcharger.common.enums.zc.ZcElecPileStopReasonEnum;
import com.rc.evcharger.common.mq.MqProducer;
import com.rc.evcharger.common.terminal.ChargeControlResult;
import com.rc.evcharger.common.terminal.RecordSource;
import com.rc.evcharger.common.utils.DataUtil;
import com.rc.evcharger.dto.terminal.ChargeBalaceResult;
import com.rc.evcharger.dto.terminal.ChargeReportResult;
import com.rc.evcharger.mapper.member.MemberInfoMapper;
import com.rc.evcharger.mapper.rc.RcOperatorMapper;
import com.rc.evcharger.model.elec.ElecGun;
import com.rc.evcharger.model.elec.ElecPile;
import com.rc.evcharger.model.elec.ElecStation;
import com.rc.evcharger.model.member.MemberInfo;
import com.rc.evcharger.model.order.OrderComment;
import com.rc.evcharger.model.order.OrderInfo;
import com.rc.evcharger.model.rc.RcOperator;
import com.rc.evcharger.service.elec.ElecGunService;
import com.rc.evcharger.service.elec.ElecPileService;
import com.rc.evcharger.service.elec.ElecStationService;
import com.rc.evcharger.vo.log.ChargedProcessLog;
import com.rc.mutievcharger.dto.ylevcharger.terminal.req.YlChargingCommandReq;
import com.rc.mutievcharger.dto.ylevcharger.terminal.req.YlStartCommandReq;
import com.rc.mutievcharger.dto.ylevcharger.terminal.req.YlTransactionsCommandReq;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 充电日志组装器
 * Create by Yang on 2019/11/21
 */
@Component
public class ChargedProcessLogAssemble {
    private static Logger logger = LoggerFactory.getLogger(ChargedProcessLogAssemble.class);
    private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss,SSS");

    @Autowired
    private MqProducer mqProducer;

    @Autowired
    private ElecGunService elecGunService;

    @Autowired
    private RcOperatorMapper rcOperatorMapper;

    @Autowired
    private MemberInfoMapper memberInfoMapper;

    @Autowired
    private ElecStationService elecStationService;

    @Autowired
    private ElecPileService elecPileService;

    @Autowired
    private MqCommandConfig mqCommandConfig;

    public void sendChargedProcessLog(ChargedProcessLog log) {
        ObjectMapper objectMapper = new ObjectMapper();

        //推送日志消息
        try {
            String json = objectMapper.writeValueAsString(log);
            mqProducer.send(RabbitListenerConstant.DOMAIN_LOG_CHARGED_PROCESS_QUEUE, json);
        } catch (Exception e) {
            logger.error("ChargedProcessLogAssemble推送日志消息报错", e);
        }
    }

    /**
     * 封装充电中、充电结束上报数据
     *
     * @param phase
     * @param recordSource
     * @param orderInfo
     */
    public void assembleChargedProcessLog(ChargePhaseEnum phase, RecordSource recordSource,
                                          OrderInfo orderInfo, BigDecimal elecAmount, BigDecimal serviceAmount) {

        //推送日志消息
        ChargedProcessLog chargedProcessLog = new ChargedProcessLog(orderInfo.getStartTime());

        //订单信息
        chargedProcessLog.setTenantCode(orderInfo.getTenantCode());
        chargedProcessLog.setTenantOperatorCode(orderInfo.getTenantOperatorCode());
        chargedProcessLog.setHlhtTenantCode(orderInfo.getHlhtTenantCode());
        chargedProcessLog.setHlhtOperatorId(orderInfo.getHlhtOperatorId());

        chargedProcessLog.setOrderNum(orderInfo.getOrderNum());
        chargedProcessLog.setOutOrderNum(orderInfo.getOutOrderNum());

        //充电过程
        chargedProcessLog.setPhase(phase.getMsg());

        //站点编号
        ElecStation elecStation = elecStationService.selectByPrimaryKey(orderInfo.getElecStationId());
        chargedProcessLog.setStaionName(elecStation.getStationName());
        //加盟商
        RcOperator rcOperator = rcOperatorMapper.selectByPrimaryKey(elecStation.getOperatorId());
        chargedProcessLog.setOperatorName(rcOperator.getOperatorName());    //新增加盟商名称


        //枪编号
        ElecGun elecGun = elecGunService.selectByPrimaryKey(orderInfo.getElecGunId());
        chargedProcessLog.setGunNo(elecGun.getGunNo());
        //桩短号
        ElecPile elecPile = elecPileService.selectByPrimaryKey(elecGun.getElecPileId());
        chargedProcessLog.setPileSort(elecPile.getPileSort()); //桩短号

        MemberInfo memberInfo = memberInfoMapper.selectByPrimaryKey(orderInfo.getMemberId());
        chargedProcessLog.setMobile(memberInfo.getMobile());
        chargedProcessLog.setNickName(memberInfo.getNickname2());
        chargedProcessLog.setCarNumber(orderInfo.getCarNum());


        //充电中
        if (recordSource instanceof ChargeReportResult) {
            ChargeReportResult chargeReportResult = (ChargeReportResult) recordSource;

            //实时数据
            chargedProcessLog.setVoltage(chargeReportResult.getVoltage() == null ? "0" : chargeReportResult.getVoltage().toString());
            chargedProcessLog.setElec(chargeReportResult.getElec() == null ? "0" : chargeReportResult.getElec().toString());
            //功率
            BigDecimal gunPower = chargeReportResult.getVoltage().multiply(chargeReportResult.getElec()).divide(new BigDecimal("1000")).setScale(2, BigDecimal.ROUND_HALF_UP);
            chargedProcessLog.setGunPower(gunPower.toString());

            chargedProcessLog.setPower(chargeReportResult.getPower().toString());
            chargedProcessLog.setSoc(chargeReportResult.getSoc() == null ? "0" : chargeReportResult.getSoc().toString());
            chargedProcessLog.setVin(chargeReportResult.getSvin());
            chargedProcessLog.setMaxElec(chargeReportResult.getMaxElec() == null ? "" : chargeReportResult.getMaxElec().toString());
            chargedProcessLog.setMaxVoltage(chargeReportResult.getMaxVoltage() == null ? "" : chargeReportResult.getMaxVoltage().toString());
            chargedProcessLog.setTemperatureHigh(chargeReportResult.getTemperatureHigh() == null ? "" : chargeReportResult.getTemperatureHigh().toString());
            //枪温度
            chargedProcessLog.setTemperatureGun(chargedProcessLog.getTemperatureHigh());
            chargedProcessLog.setTemperatureLow(chargeReportResult.getTemperatureLow() == null ? "" : chargeReportResult.getTemperatureLow().toString());
            //BMS温度
            chargedProcessLog.setDemandElec(chargeReportResult.getDemandElec() == null ? "" : chargeReportResult.getDemandElec().toString());
            chargedProcessLog.setDemandVoltage(chargeReportResult.getDemandVoltage() == null ? "" : chargeReportResult.getDemandVoltage().toString());
            chargedProcessLog.setServiceAmount(serviceAmount == null ? "0" : serviceAmount.toString());
            chargedProcessLog.setElecAmount(elecAmount == null ? "0" : elecAmount.toString());
            //总金额
            chargedProcessLog.setTotalAmount(new BigDecimal(chargedProcessLog.getElecAmount()).add(new BigDecimal(chargedProcessLog.getElecAmount())).toString());
            //充电结束上报
        } else if (recordSource instanceof ChargeBalaceResult) {
            ChargeBalaceResult chargeBalaceResult = (ChargeBalaceResult) recordSource;
//            chargedProcessLog.setPhase(ChargePhaseEnum.STOP_FINSHED.getMsg());

            //结算数据
            chargedProcessLog.setVoltage(chargeBalaceResult.getVoltage() == null ? "" : chargeBalaceResult.getVoltage().toString());
            chargedProcessLog.setElec(chargeBalaceResult.getElec() == null ? "" : chargeBalaceResult.getElec().toString());
            chargedProcessLog.setPower(chargeBalaceResult.getPower().toString());
            chargedProcessLog.setSoc(chargeBalaceResult.getSoc().toString());
            chargedProcessLog.setVin(chargeBalaceResult.getSvin());


            //更新停止原因
            String elecPileStopReasonResult = "";
//            if (factoryDomain.getFACTORY_LNC_DOMAIN().equals(elecPile.getElecServerDomain())) {
//                elecPileStopReasonResult = LncStopReasonEnum.getLncStopReasonEnum(chargeBalaceResult.getElecPileStopReason());
//            } else if (factoryDomain.getFACTORY_SH_DOMAIN().equals(elecPile.getElecServerDomain())) {
//                elecPileStopReasonResult = ShStopReasonEnum.getStopReasonMsg(DataUtil.turnValue(chargeBalaceResult.getElecPileStopReason()));
//            } else if (factoryDomain.getFACTORY_RS_DOMAIN().equals(elecPile.getElecServerDomain())) {
//                elecPileStopReasonResult = RsStopReasonEnum.getStopReasonResultWithInt(chargeBalaceResult.getElecPileStopReason());
//            } else {
//                elecPileStopReasonResult = ElecPileStopReasonEnum.getElecPileStopReasonResult(chargeBalaceResult.getElecPileStopReason());
//            }
            elecPileStopReasonResult = ElecPileStopReasonEnum.getElecPileStopReasonResult(chargeBalaceResult.getElecPileStopReason());
            chargedProcessLog.setElecPileFault(elecPileStopReasonResult);
            chargedProcessLog.setPowerA(chargeBalaceResult.getPowerA() == null ? "" : chargeBalaceResult.getPowerA().toString());
            chargedProcessLog.setPowerB(chargeBalaceResult.getPowerB() == null ? "" : chargeBalaceResult.getPowerB().toString());
            chargedProcessLog.setServiceAmount(serviceAmount == null ? "0" : serviceAmount.toString());
            chargedProcessLog.setElecAmount(elecAmount == null ? "0" : elecAmount.toString());
        } else if (recordSource instanceof YlChargingCommandReq) {
            YlChargingCommandReq chargingCommandReq = (YlChargingCommandReq) recordSource;
//            chargedProcessLog.setPhase(ChargePhaseEnum.STOP_FINSHED.getMsg());

            //结算数据
            chargedProcessLog.setVoltage(chargingCommandReq.getVoltage() == null ? "" : chargingCommandReq.getVoltage().toString());
            chargedProcessLog.setElec(chargingCommandReq.getElec() == null ? "" : chargingCommandReq.getElec().toString());
            chargedProcessLog.setPower(chargingCommandReq.getPower().toString());
            chargedProcessLog.setSoc(chargingCommandReq.getSoc().toString());
            //chargedProcessLog.setVin(chargingCommandReq.getSvin());

            //故障码反转，再判断
//            String hardwareFault = chargingCommandReq.getHardwareFault();
//            String elecPileStopReasonResult = ZcElecPileStopReasonEnum.getElecPileStopReasonResult(DataUtil.turnValue(hardwareFault));
//            if (factoryDomain.getFACTORY_RS_DOMAIN().equals(elecPile.getElecServerDomain())) {
//                elecPileStopReasonResult = RsWarnCodeEnum.getRsWarnCode(Integer.valueOf(chargingCommandReq.getHardwareFault()));
//            }
//            chargedProcessLog.setElecPileFault(elecPileStopReasonResult);
            //chargedProcessLog.setPowerA(chargingCommandReq.getPowerA().toString());
            //chargedProcessLog.setPowerB(chargingCommandReq.getPowerB().toString());
            chargedProcessLog.setServiceAmount(serviceAmount == null ? "0" : serviceAmount.toString());
            chargedProcessLog.setElecAmount(elecAmount == null ? "0" : elecAmount.toString());
        } else if (recordSource instanceof YlTransactionsCommandReq) {
            YlTransactionsCommandReq transactionsCommandReq = (YlTransactionsCommandReq) recordSource;
//            chargedProcessLog.setPhase(ChargePhaseEnum.STOP_FINSHED.getMsg());

            //结算数据
            //chargedProcessLog.setVoltage(chargingCommandReq.getVoltage().toString());
            //chargedProcessLog.setElec(chargingCommandReq.getElec().toString());
            chargedProcessLog.setPower(transactionsCommandReq.getPower() == null ? "" : transactionsCommandReq.getPower().toString());
            //chargedProcessLog.setSoc(chargingCommandReq.getSoc().toString());
            //chargedProcessLog.setVin(chargingCommandReq.getSvin());

            //故障码反转，再判断
//            String elecPileStopReasonResult = ZcElecPileStopReasonEnum.getElecPileStopReasonResult(transactionsCommandReq.getStopResult());
//            if (factoryDomain.getFACTORY_RS_DOMAIN().equals(elecPile.getElecServerDomain())) {
//                elecPileStopReasonResult = RsStopReasonEnum.getStopReasonResultWithInt(transactionsCommandReq.getStopResult());
//            }
//            chargedProcessLog.setElecPileFault(elecPileStopReasonResult);
            //chargedProcessLog.setPowerA(chargingCommandReq.getPowerA().toString());
            //chargedProcessLog.setPowerB(chargingCommandReq.getPowerB().toString());
            chargedProcessLog.setServiceAmount(serviceAmount == null ? "0" : serviceAmount.toString());
            chargedProcessLog.setElecAmount(elecAmount == null ? "0" : elecAmount.toString());
        }


        //推送日志消息
        this.sendChargedProcessLog(chargedProcessLog);
    }

    /**
     * 桩回复 启停充电
     *
     * @param recordSource
     * @param orderComment
     */
    public void assembleChargedProcessLog(RecordSource recordSource, OrderComment orderComment) {
        //推送日志消息
        ChargedProcessLog chargedProcessLog = new ChargedProcessLog(new Date());

        //订单信息
        chargedProcessLog.setTenantCode(orderComment.getTenantCode());
        chargedProcessLog.setTenantOperatorCode(orderComment.getTenantOperatorCode());
        chargedProcessLog.setHlhtTenantCode(orderComment.getHlhtTenantCode());
        chargedProcessLog.setHlhtOperatorId(orderComment.getHlhtOperatorId());

        chargedProcessLog.setOrderNum(orderComment.getOrderNum());
        chargedProcessLog.setOutOrderNum(orderComment.getOutOrderNum());

        //站点编号
        ElecStation elecStation = elecStationService.selectByPrimaryKey(orderComment.getElecStationId());
        chargedProcessLog.setStationName(elecStation.getStationName());

        //枪编号
        ElecGun elecGun = elecGunService.selectByPrimaryKey(orderComment.getElecGunId());
        chargedProcessLog.setGunNo(elecGun.getGunNo());

        //实时数据
        if (recordSource instanceof ChargeControlResult) {
            ChargeControlResult chargeControlResult = (ChargeControlResult) recordSource;
            //桩反馈结果
            switch (chargeControlResult.getExecuteResult()) {
                case "01":
                    chargedProcessLog.setPhase(ChargePhaseEnum.START_FINSHED.getMsg());
                    break;
                case "02":
                    chargedProcessLog.setPhase(ChargePhaseEnum.START_FAIL.getMsg());
                    break;
                case "03":
                    chargedProcessLog.setPhase(ChargePhaseEnum.STOP_FINSHED.getMsg());
                    break;
                case "04":
                    chargedProcessLog.setPhase(ChargePhaseEnum.STOPING.getMsg());
                    break;
                default:
                    chargedProcessLog.setPhase(ChargePhaseEnum.UNKNOWN_STATUS.getMsg() + ":" + chargeControlResult.getExecuteResult());
            }

            if (chargeControlResult.getFailReason() != null) {
                //桩启动或停止原因 启动失败：1.未插枪 2.启动故障 3.正在充电中 4.订单号不符 5.未在充电中
                switch (chargeControlResult.getFailReason()) {

                    case "00":
                        chargedProcessLog.setElecPileFault("");
                        break;
                    case "01":
                        chargedProcessLog.setElecPileFault("未插枪");
                        break;
                    case "02":
                        chargedProcessLog.setElecPileFault("启动故障");
                        break;
                    case "03":
                        chargedProcessLog.setElecPileFault("正在充电中");
                        break;
                    case "04":
                        chargedProcessLog.setElecPileFault("订单号不符");
                        break;
                    case "05":
                        chargedProcessLog.setElecPileFault("未在充电中");
                        break;
                    default:
                        chargedProcessLog.setPhase(ChargePhaseEnum.UNKNOWN_STATUS.getMsg());
                }
            }


        } else if (recordSource instanceof YlStartCommandReq) {
            YlStartCommandReq startCommandReq = (YlStartCommandReq) recordSource;
            if (startCommandReq.getResult().intValue() == 0) {
                chargedProcessLog.setPhase(ChargePhaseEnum.START_FINSHED.getMsg());
                chargedProcessLog.setElecPileFault("启动成功");
            } else {
                chargedProcessLog.setPhase(ChargePhaseEnum.START_FAIL.getMsg());
                chargedProcessLog.setElecPileFault("启动失败");
            }
        }

        //推送日志消息
        this.sendChargedProcessLog(chargedProcessLog);
    }


    /**
     * @param phase
     * @param orderComment
     */
    public void assembleChargedProcessLog(ChargePhaseEnum phase, OrderComment orderComment) {

        //推送日志消息
        ChargedProcessLog chargedProcessLog = new ChargedProcessLog(new Date());

        //站点编号
        ElecStation elecStation = elecStationService.selectByPrimaryKey(orderComment.getElecStationId());
        chargedProcessLog.setStationName(elecStation.getStationName());

        //枪编号
        ElecGun elecGun = elecGunService.selectByPrimaryKey(orderComment.getElecGunId());
        chargedProcessLog.setGunNo(elecGun.getGunNo());

        //订单信息
        chargedProcessLog.setTenantCode(orderComment.getTenantCode());
        chargedProcessLog.setTenantOperatorCode(orderComment.getTenantOperatorCode());
        chargedProcessLog.setHlhtTenantCode(orderComment.getHlhtTenantCode());
        chargedProcessLog.setHlhtOperatorId(orderComment.getHlhtOperatorId());

        chargedProcessLog.setOrderNum(orderComment.getOrderNum());
        chargedProcessLog.setOutOrderNum(orderComment.getOutOrderNum());

        String commanderEnum = CommanderEnum.getCommanderEnum(orderComment.getOrderSource());
//        chargedProcessLog.setConnectorStatus(GqConfig.OperatorID);
        //终端+充电过程
        chargedProcessLog.setPhase(commanderEnum + phase.getMsg());

        //推送日志消息
        this.sendChargedProcessLog(chargedProcessLog);
    }


    /**
     * 平台扫描停止日志
     *
     * @param phase
     * @param orderInfo
     */
    public void assembleChargedProcessLog(ChargePhaseEnum phase, OrderInfo orderInfo) {


        //推送日志消息
        ChargedProcessLog chargedProcessLog = new ChargedProcessLog(orderInfo.getStartTime());

        //站点编号
        ElecStation elecStation = elecStationService.selectByPrimaryKey(orderInfo.getElecStationId());
        chargedProcessLog.setStationName(elecStation.getStationName());

        //枪编号
        ElecGun elecGun = elecGunService.selectByPrimaryKey(orderInfo.getElecGunId());
        chargedProcessLog.setGunNo(elecGun.getGunNo());

        //订单信息
        chargedProcessLog.setTenantCode(orderInfo.getTenantCode());
        chargedProcessLog.setTenantOperatorCode(orderInfo.getTenantOperatorCode());
        chargedProcessLog.setHlhtTenantCode(orderInfo.getHlhtTenantCode());
        chargedProcessLog.setHlhtOperatorId(orderInfo.getHlhtOperatorId());

        chargedProcessLog.setOrderNum(orderInfo.getOrderNum());
        chargedProcessLog.setOutOrderNum(orderInfo.getOutOrderNum());

        chargedProcessLog.setPower(orderInfo.getTotalPower().toString());
        chargedProcessLog.setSoc(orderInfo.getSoc().toString());
        chargedProcessLog.setVin(orderInfo.getCarVin());
        chargedProcessLog.setServiceAmount(orderInfo.getTotalSeviceMoney().toString());
        chargedProcessLog.setElecAmount(orderInfo.getTotalElecMoney().toString());

        //终端+充电过程
        if (ChargePhaseEnum.SETTLED.getMsg().equals(chargedProcessLog.getPhase())) {
            chargedProcessLog.setPhase("平台扫描停止 " + phase.getMsg());
        } else {
            chargedProcessLog.setPhase("mongdb扫描停止 " + phase.getMsg());
        }

        //推送日志消息
        this.sendChargedProcessLog(chargedProcessLog);
    }


}
